/*
 * Sylvain BERTRAND <digital.ragnarok@gmail.com>
 * code protected by GNU GPL v3
 */
#include <string.h>
#include <X11/Xlib.h>
#include <glib.h>
#include <libxml/xinclude.h>
#include "../../nls.h"
#include "../../toolkit/keyboard.h"
#include "../../toolkit/xml.h"
#include "../../toolkit/paths.h"
#include "../misc.h"
#include "../geom.h"
#include "../frame.h"
#include "../actions.h"
#include "../window.h"
#include "../stacking.h"
#include "../client.h"
#include "../event.h"
#include "../screen.h"
struct options {
	gchar *cmd;
	struct wm_actions_data *data;
};

static gpointer setup_func(xmlNodePtr node)
{
	xmlNodePtr n;
	struct options *o;
	o = g_slice_new0(struct options);
	if((n = t_xml_find_node(node, "command")) || (n = t_xml_find_node(node, "execute"))) {
		gchar *s = t_xml_node_string(n);
		o->cmd = t_paths_expand_tilde(s);
		g_free(s);
	}
	return o;
}

static void free_func(gpointer options)
{
	struct options *o = options;
	if(o) {
		g_free(o->cmd);
		if(o->data)
			g_slice_free(struct wm_actions_data, o->data);
		g_slice_free(struct options, o);
	}
}

static gboolean run_func(struct wm_actions_data *data, gpointer options)
{
	GError *e;
	gchar **argv = NULL;
	gchar *cmd;
	struct options *o = options;
	if(!o->cmd)
		return FALSE;

	cmd = g_filename_from_utf8(o->cmd, -1, NULL, NULL, NULL);
	if(!cmd) {
		g_message(_("Failed to convert the path \"%s\" from utf8"), o->cmd);
		return FALSE;
	}
	if(data->client) {
		gchar *c, *before, *expand;
		expand = NULL;
		before = cmd;
		while((c = strchr(before, '$'))) {
			if((c[1] == 'p' || c[1] == 'P') && (c[2] == 'i' || c[2] == 'I') && (c[3] == 'd' || c[3] == 'D')
				&& !g_ascii_isalnum(c[4])) {
				gchar *tmp;
				*c = '\0';
				tmp = expand;
				expand = g_strdup_printf("%s%s%u", (expand ? expand : ""), before, data->client->pid);
				g_free(tmp);
				before = c + 4;
			} else if((c[1] == 'w' || c[1] == 'W') && (c[2] == 'i' || c[2] == 'I') && (c[3] == 'd' || c[3] == 'D')
				&& !g_ascii_isalnum(c[4])) {
				gchar *tmp;
				*c = '\0';
				tmp = expand;
				expand = g_strdup_printf("%s%s%lu", (expand ? expand : ""), before, data->client->window);
				g_free(tmp);
				before = c + 4;
			} else
				before = c + 1;
		}
		if(expand) {
			gchar *tmp;
			tmp = expand;
			expand = g_strconcat(expand, before, NULL);
			g_free(tmp);
			g_free(cmd);
			cmd = expand;
		}
	}
	e = NULL;
	if(!g_shell_parse_argv(cmd, NULL, &argv, &e)) {
		g_message("%s", e->message);
		g_error_free(e);
	} else {
		gchar *program = NULL;
		gboolean ok;
		e = NULL;
		ok = g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, NULL, &e);
		if(!ok) {
			g_message("%s", e->message);
			g_error_free(e);
		}
		g_free(program);
		g_strfreev(argv);
	}
	g_free(cmd);
	return FALSE;
}

void action_execute_startup(void)
{
	actions_register("Execute", setup_func, free_func, run_func);
}
